#include "Snake.h"
#include "Game_page.h"
#include "IniProgram.h"
#include "music.h"
#include <iostream>
#include <chrono>

char *characterImages[] = {
    "./res/head.bmp",            // 默认头像
    "./res/head_Flower_hat.bmp", // 花帽
    "./res/head_Sunglasses.bmp"  // 太阳镜
};

Snake::Snake(Container *parent, int segmentSize, int overlap, int initialLength, int speed, ClotherType type)
    : segmentSize(segmentSize), overlapAmount(overlap), maxHistoryLength(1000), moveSpeed(speed)
{
    currentDirection.store(DIRECTION_RIGHT);
    isMoving.store(false);
    isRunning.store(true);

    Snake_head = characterImages[type];

    // 创建所有蛇段，按渲染顺序插入：蛇尾→蛇身→蛇头（先渲染的在前）
    for (int i = initialLength - 1; i >= 0; i--)
    {
        Container *segment = new Container(parent, segmentSize, segmentSize);

        int segmentX = 100 - (i * (segmentSize - overlapAmount));
        int segmentY = 240;
        segment->set_pos(segmentX, segmentY);
        segment->set_Visible(true);

        // 设置不同段的图片
        if (i == 0)
        {
            segment->set_background_image(Snake_head, true, 0x00ffffff); // 蛇头
        }
        else if (i == initialLength - 1)
        {
            segment->set_background_image("./res/tail.bmp", true, 0x00ffffff); // 蛇尾
        }
        else
        {
            segment->set_background_image("./res/body.bmp", true, 0x00ffffff); // 蛇身
        }

        // 始终插入到begin处，确保渲染顺序正确
        bodySegments.insert(bodySegments.begin(), segment);

        // 记录位置历史
        for (int j = 0; j < (initialLength - i) * 3; j++)
        {
            positionHistory.push_front(std::make_pair(segmentX, segmentY));
        }
    }

    moveThread = std::thread(&Snake::moveThreadFunc, this);
}

Snake::~Snake()
{
    isMoving.store(false); // 先停止移动
    isRunning.store(false);

    if (moveThread.joinable())
    {
        moveThread.join(); // 等待线程结束
        cout << "线程终止" << endl;
    }

    int i = 0;

    // 从父容器中移除所有蛇身段
    for (auto segment : bodySegments)
    {

        if (segment != nullptr)
        {
            // 如果蛇身段有父容器，从父容器中移除
            if (segment->isIniParent())
            {
                Container *parent = segment->getParent();
                if (parent != nullptr)
                {
                    parent->removeSon(segment);
                }
            }

            // 删除蛇身段对象
            delete segment;
        }
    }

    bodySegments.clear();
    positionHistory.clear();
}

void Snake::startMoving()
{
    if (isMoving.load())
        return;

    isMoving.store(true);
    // 不再需要创建线程，因为线程已经在构造函数中创建
}

void Snake::stopMoving()
{
    isMoving.store(false);
}

void Snake::moveThreadFunc()
{
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    while (isRunning.load())
    {
        if (!isMoving.load())
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(50));
            continue; // 跳过移动逻辑
        }

        // manager.tryLockRender();

        int direction = currentDirection.load();
        Container *head = getHead();
        if (head == nullptr)
        {
            cout << "错误导致蛇头节点为空" << endl;
            continue;
        }

        int currentX = head->get_pos_x();
        int currentY = head->get_pos_y();
        int newX = currentX;
        int newY = currentY;

        // 根据方向移动（移动距离 = 段大小 - 重叠量，保持重叠效果）
        int moveDistance = 5; // 固定步长

        switch (direction)
        {
        case DIRECTION_RIGHT:
            newX += moveDistance;
            break;
        case DIRECTION_UP_RIGHT:
            newX += moveDistance;
            newY -= moveDistance;
            break;
        case DIRECTION_UP:
            newY -= moveDistance;
            break;
        case DIRECTION_UP_LEFT:
            newX -= moveDistance;
            newY -= moveDistance;
            break;
        case DIRECTION_LEFT:
            newX -= moveDistance;
            break;
        case DIRECTION_DOWN_LEFT:
            newX -= moveDistance;
            newY += moveDistance;
            break;
        case DIRECTION_DOWN:
            newY += moveDistance;
            break;
        case DIRECTION_DOWN_RIGHT:
            newX += moveDistance;
            newY += moveDistance;
            break;
        case DIRECTION_NONE:
            // 不移动
            break;
        }

        // 移动蛇头
        moveHead(newX, newY);

        // 检查食物碰撞

        // foodManager->updateFoods(*gameSnake);

        if (foodManager != nullptr)
        {
            Food *collidedFood = foodManager->checkCollision(*this);
            if (collidedFood != nullptr)
            {
                foodManager->handleCollision(collidedFood, this);
                foodManager->generateRandomFood(*gameSnake);
            }
        }
        else
        {
            cout << "foodManager 为空指针" << endl;
        }

        // manager.unlockRender();
        // 休眠控制移动速度
        std::this_thread::sleep_for(std::chrono::milliseconds(moveSpeed));
    }
}

void Snake::setDirection(int direction)
{
    int currentDir = currentDirection.load();

    // 防止直接反向移动
    bool isOpposite = false;
    if ((currentDir == DIRECTION_RIGHT && direction == DIRECTION_LEFT) ||
        (currentDir == DIRECTION_LEFT && direction == DIRECTION_RIGHT) ||
        (currentDir == DIRECTION_UP && direction == DIRECTION_DOWN) ||
        (currentDir == DIRECTION_DOWN && direction == DIRECTION_UP))
    {
        isOpposite = true;
    }

    if (!isOpposite && direction != DIRECTION_NONE)
    {
        currentDirection.store(direction);
        // std::cout << "蛇方向改为: " << direction << std::endl;
    }
}

void Snake::moveHead(int newX, int newY)
{
    if (bodySegments.empty())
        return;

    Container *head = bodySegments[0];
    if (head == nullptr)
    {
        cout << "意外导致蛇头指针为空" << endl;
        return;
    }

    // 添加位置前检查历史记录大小
    if (positionHistory.size() >= maxHistoryLength)
    {
        positionHistory.pop_back(); // 移除最旧的记录
    }

    positionHistory.push_front(std::make_pair(newX, newY));
    head->set_pos(newX, newY);
    updateBody();
}

void Snake::updateBody()
{
    if (bodySegments.size() <= 1)
        return;

    // 更新每个蛇身段的位置，实现重叠跟随效果
    for (size_t i = 1; i < bodySegments.size(); i++)
    {
        // 更安全的历史索引计算
        size_t historyIndex = i * 2; // 简化计算，每个身体段间隔2个历史记录

        // 加强边界检查
        if (historyIndex >= positionHistory.size())
        {
            // 使用最后一个有效位置
            historyIndex = positionHistory.size() - 1;
        }

        if (i < bodySegments.size() && historyIndex < positionHistory.size())
        {
            int targetX = positionHistory[historyIndex].first;
            int targetY = positionHistory[historyIndex].second;

            if (bodySegments[i] != nullptr)
            {
                bodySegments[i]->set_pos(targetX, targetY);
            }
        }
    }

    if (positionHistory.size() > maxHistoryLength)
    {
        positionHistory.resize(maxHistoryLength);
    }

    if (checkBoundaryCollision(800, 480))
    {
        std::cout << "游戏结束！蛇撞到边界了！" << std::endl;
        stopMoving();
        Display_Game_Over_Page();
    }
}

void Snake::grow()
{
    if (bodySegments.empty())
        return;

    // 获取当前蛇尾（vector的第一个元素，因为是最先渲染的）
    Container *currentTail = bodySegments.back();

    int insertIndex = 0; // 默认插入到最底层

    if (currentTail->isIniParent())
    {
        Container *parent = currentTail->getParent();
        // 找到当前蛇尾在父容器子容器列表中的位置
        for (size_t i = 0; i < parent->get_son_count(); i++)
        {
            if (parent->getSon(i) == currentTail)
            {
                insertIndex = i; // 在蛇尾的位置插入，蛇尾会被推到后面
                break;
            }
        }
    }

    // 创建新的尾巴段
    Container *newTail = new Container(currentTail->isIniParent() ? currentTail->getParent() : nullptr,
                                       segmentSize, segmentSize,
                                       currentTail->get_pos_x(), currentTail->get_pos_y(),
                                       insertIndex);
    newTail->set_background_image(get_Snake_tail(), true, 0x00ffffff);
    newTail->set_Visible(true);
    // newTail->set_pos(currentTail->get_pos_x(), currentTail->get_pos_y());

    // 将原来的尾巴改为身体
    currentTail->set_background_image(get_Snake_body(), true, 0x00ffffff);

    // 为新的蛇尾创建历史记录
    int historyEntries = 5; // 计算需要的历史记录数量

    // 获取当前蛇尾的位置
    int tailX = currentTail->get_pos_x();
    int tailY = currentTail->get_pos_y();

    // 为新段创建历史记录
    for (int j = 0; j < historyEntries; j++)
    {
        positionHistory.push_back(std::make_pair(tailX, tailY)); // 添加到队列末尾
    }

    if (positionHistory.size() > maxHistoryLength)
    {
        positionHistory.resize(maxHistoryLength);
    }

    // 新尾巴插入到begin处（最先渲染）
    // bodySegments.insert(bodySegments.end(), newTail);
    bodySegments.push_back(newTail);

    // 更新最大历史记录长度
    maxHistoryLength = std::max(maxHistoryLength, (int)positionHistory.size());
}

void Snake::shrink(int amount)
{
    // 确保蛇身至少保留4个节点
    if (bodySegments.size() <= 4 || amount <= 0)
    {
        return; // 蛇身至少保留4节，或者减少数量无效
    }

    // 确保不会减少到少于4节
    int actualAmount = std::min(amount, static_cast<int>(bodySegments.size()) - 4);

    for (int i = 0; i < actualAmount; i++)
    {
        if (bodySegments.size() <= 4)
        {
            break; // 确保至少保留4节
        }

        // 获取并删除蛇尾（vector的最后一个元素）
        Container *tailToRemove = bodySegments.back();

        // 从父容器中移除（如果存在父容器）
        if (tailToRemove->isIniParent())
        {
            Container *parent = tailToRemove->getParent();
            parent->removeSon(tailToRemove);
        }

        // 从蛇身段列表中移除
        bodySegments.pop_back();

        // 删除蛇尾容器对象
        delete tailToRemove;

        // 如果删除后还有多于4节，将新的蛇尾设置为尾巴图片
        if (bodySegments.size() > 4)
        {
            Container *newTail = bodySegments.back();
            newTail->set_background_image(get_Snake_tail(), true, 0x00FFFFFF);
        }

        // 清理相应的历史记录（可选，为了保持位置跟踪的准确性）
        if (positionHistory.size() > 10)
        {
            // 移除最近的一些历史记录，数量可以根据重叠量调整
            int recordsToRemove = 5;
            for (int j = 0; j < recordsToRemove && !positionHistory.empty(); j++)
            {
                positionHistory.pop_back();
            }
        }
    }
}

Container *Snake::getHead() const
{
    if (bodySegments.empty())
        return nullptr;
    return bodySegments[0]; // 蛇头总是在最前面
}

// 修改蛇头的背景图片
void Snake::setHeadImage(const char *imagePath)
{
    if (bodySegments.empty() || imagePath == nullptr)
        return;

    // 蛇头是bodySegments的第一个元素
    Container *head = bodySegments.front();
    if (head != nullptr)
    {
        head->set_background_image(imagePath, true, 0x00FFFFFF);
    }
}

void Snake::setBodySegmentsImage(const char *imagePath)
{
    if (bodySegments.empty() || imagePath == nullptr)
        return;

    for (size_t i = 0; i < bodySegments.size(); i++)
    {
        if (bodySegments[i] != nullptr)
        {
            bodySegments[i]->set_background_image(imagePath, true, 0x00FFFFFF);
        }
    }
}

// 修改蛇尾的背景图片
void Snake::setTailImage(const char *imagePath)
{
    if (bodySegments.empty() || imagePath == nullptr)
        return;

    // 蛇尾是bodySegments的最后一个元素
    Container *tail = bodySegments.back();
    if (tail != nullptr)
    {
        tail->set_background_image(imagePath, true, 0x00FFFFFF);
    }
}

bool Snake::checkBoundaryCollision(int maxWidth, int maxHeight) const
{
    if (bodySegments.empty())
        return false;

    Container *head = bodySegments[0];
    int headX = head->get_pos_x();
    int headY = head->get_pos_y();
    int headWidth = head->get_width();
    int headHeight = head->get_height();

    // 使用矩形边界检测
    bool collision = (headX < 0 || headY < 0 ||
                      headX + headWidth > maxWidth ||
                      headY + headHeight > maxHeight);

    return collision;
}

bool Snake::checkCollisionWithContainer(Container *other) const
{
    if (bodySegments.empty() || other == nullptr)
        return false;

    Container *head = bodySegments[0];
    int headX = head->get_pos_x();
    int headY = head->get_pos_y();
    int headWidth = head->get_width();
    int headHeight = head->get_height();

    int otherX = other->get_pos_x();
    int otherY = other->get_pos_y();
    int otherWidth = other->get_width();
    int otherHeight = other->get_height();

    // 使用矩形边界碰撞检测
    bool xCollision = (headX < otherX + otherWidth) && (headX + headWidth > otherX);
    bool yCollision = (headY < otherY + otherHeight) && (headY + headHeight > otherY);

    return xCollision && yCollision;
}
